package assetList.testsuites;

import base.originBase.BaseParameter;
import base.originBase.BaseTemplate;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import java.math.BigDecimal;
import java.util.List;

public class AssetList extends BaseTemplate {

    @BeforeTest
    public void initialize() {
    }

    @Test(dataProvider = "data")
    @Override
    public void testCase(String comment, List<BaseParameter> paramterList) {
        doIt(paramterList, comment);
//        if (getStepResults().size() != 2)
//            logger.error("step的数量不对，没有获取全部的数据");
//        //基金持仓详情页
//        String day = getStepResults().get(0);
//        //基金净值列表4个数
//        String nav = getStepResults().get(1);
//        JSONObject dayJson = JSON.parseObject(day);
//        JSONObject navJson = JSON.parseObject(nav);
//        List navData = (List) ((JSONObject) navJson.get("data")).get("records");
//        BigDecimal dayInc1 = ((JSONObject) (navData.get(0))).getBigDecimal("fNavUnit");
//        BigDecimal dayInc2 = ((JSONObject) (navData.get(1))).getBigDecimal("fNavUnit");
//        //2日净值差
//        BigDecimal disDayNavUnit = dayInc1.subtract(dayInc2);
//        // 份额
//        BigDecimal holdingShare = ((JSONObject) (dayJson.get("data"))).getBigDecimal("holdingShare");
//        int incomeScale = 2;
//        //接口昨日
//        BigDecimal testYesterdayIncome = ((JSONObject) (dayJson.get("data"))).getBigDecimal("lastDayProfit");
//        //昨日收益
//        BigDecimal yesterdayIncome = disDayNavUnit.multiply(holdingShare);
//
//        //接口日涨幅
//        BigDecimal testDailyIncrement = ((JSONObject) (dayJson.get("data"))).getBigDecimal("dailyIncrement");
//        // 昨日涨幅
//        BigDecimal yesterdayIncrement = disDayNavUnit.divide(dayInc2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
//
//        //持仓金额计算
//        //持有金额
//        BigDecimal holdingAsset = ((JSONObject) (dayJson.get("data"))).getBigDecimal("holdingAsset");
//        //在途
//        BigDecimal onWayAsset = ((JSONObject) (dayJson.get("data"))).getBigDecimal("onWayAsset");
//        // 总金额
//        BigDecimal totalAsset = ((JSONObject) (dayJson.get("data"))).getBigDecimal("totalAsset");
//
//        //基金净值
//        //昨日净值
//        String pernetValue = ((JSONObject) dayJson.get("data")).getString("pernetValue");
//        String testValue = ((JSONObject) (navData.get(0))).getString("fNavUnit");
//
//        boolean allTest = true;
//        //昨日收益一定满足
//        boolean isPass = testIncome(yesterdayIncome, testYesterdayIncome, incomeScale);
//        logger.info("收益测试：" + isPass);
//        allTest = isPass && allTest;
//        // 昨日涨幅一定满足
//        isPass = testIncome(yesterdayIncrement, testDailyIncrement, incomeScale);
//        logger.info("日涨幅测试：" + isPass);
//        allTest = isPass && allTest;
//        // 总收益
//        isPass = totalAsset.compareTo(holdingAsset.add(onWayAsset)) == 0;
//        logger.info("总收益测试：" + isPass);
//        allTest = isPass && allTest;
//        //净值比较
//        isPass = pernetValue.equals(testValue);
//        logger.info("净值测试: " + isPass);
//        allTest = isPass && allTest;
//
//        Assert.assertEquals(allTest, true);
    }

    @Override
    protected String doSomethingAfterCall(String response) {
        if (StrUtil.isEmpty(response))
            return "";
        JSONObject json = JSON.parseObject(response).getJSONObject("data");

        //总金额
        BigDecimal testTotalAsset = json.getBigDecimal("totalAsset");
        //总昨日收益
        BigDecimal testLastDayProfit = json.getBigDecimal("lastDayProfit");
        //总持仓
        BigDecimal testTotalProfit = json.getBigDecimal("totalProfit");
        //待确认
        BigDecimal testOnWayAsset = json.getBigDecimal("onWayAsset");

        //持仓列表数据
        JSONArray assetArray = ((JSONObject) json.getJSONObject("singleAssets")).getJSONArray("assetList");
        BigDecimal calcTotalAsset = new BigDecimal("0");
        BigDecimal calcLastDayProfit = new BigDecimal("0");
        BigDecimal calcTotalProfit = new BigDecimal("0");
        BigDecimal calcOnWayAsset = new BigDecimal("0");

        for (Object x : assetArray) {
            JSONObject item = (JSONObject) x;
            calcTotalAsset = calcTotalAsset.add(item.getBigDecimal("totalAsset"));
            calcLastDayProfit = calcLastDayProfit.add(item.getBigDecimal("lastDayProfit"));
            calcTotalProfit = calcTotalProfit.add(item.getBigDecimal("holdingProfit"));
            calcOnWayAsset = calcOnWayAsset.add(item.getBigDecimal("onWayAsset"));
        }

        //计算偏差，为了方便计算多个基金合并时候的数值偏差如3只基金 偏差应该为 CEIL(3 / 2) = 2
        int n = (int) (assetArray.size() / 2) + 1;
        boolean allTest = true;
        int scale = 2;
        //总持仓
        allTest = allTest && testSummary(calcTotalAsset, testTotalAsset, scale, n, "总持仓：");
        //昨日收益
        allTest = allTest && testSummary(calcLastDayProfit, testLastDayProfit, scale, n, "昨日收益测试：");
        //总收益
        allTest = allTest && testSummary(calcTotalProfit, testTotalProfit, scale, n, "总收益：");
        //总在途
        allTest = allTest && testSummary(calcOnWayAsset, testOnWayAsset, scale, 1, "总在途：");

        Assert.assertEquals(allTest, true);
        return response;
    }

    boolean testSummary(BigDecimal calc, BigDecimal test, int scale, int n, String msg) {
        boolean isPass = testIncome(calc, test, scale, n);
        logger.info(msg + isPass);
        return isPass;
    }

    //比较±0.x * scale
    boolean testIncome(BigDecimal calc, BigDecimal test, int scale, int n) {
        //精度
        BigDecimal limit = new BigDecimal(0.1);
        for (int i = 0; i < scale - 1; ++i)
            limit = limit.multiply(limit);

        limit = limit.multiply(new BigDecimal(n)).setScale(scale, BigDecimal.ROUND_HALF_UP);

        BigDecimal distance = test.setScale(scale, BigDecimal.ROUND_HALF_UP).subtract(calc.setScale(scale, BigDecimal.ROUND_HALF_UP));
        boolean ret = distance.compareTo(limit) <= 0 && distance.compareTo(limit.multiply(new BigDecimal(-1))) >= 0;
        logger.info(calc.setScale(scale, BigDecimal.ROUND_HALF_UP).toString() + " CMP " +
                test.setScale(scale, BigDecimal.ROUND_HALF_UP).toString() + " = " + distance + "/" + limit + " >>> " + ret);
        return ret;
    }

    @Override
    public void initToken(String token) {
        setToken("access-token=\"eyJtYW1VIjoxNywibWFtVCI6IlpXUmhZbU00WXpGbVlUTTBOR0pqTVRFeFpqQXpPR0UyT0daa05UUmtPVFpqTm1JME5qSXdOMkU1WVdVeU0yWmlaVGcxTVRka016RXhNalkwTWpFM1pUWTNOR0k1T1RGaFlURTVPV1l3TlRRMk5HWXpNemd4WW1NMVpUazJPVE0xWVdFd1pqTTBNekEzT0RreU5ETm1NV1UxWkdaaU4yRm1OekU0TVRreFlUZz0iLCJtYW1DIjoiMDAxIiwiYWNjZXNzVG9rZW4iOm51bGwsImN1c3RvbWVyRGV0YWlsUmVzcCI6bnVsbH0=\"");
    }
}
